﻿using GKQC.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;

namespace GKQC.Machine
{
    public class LcrMeter19001A : ILcrMeterAuto
    {
        public static string GetVersion(SerialPort sp)
        {
            bool flag = false;

            byte[] SendBytes = null;
            string SendData = "*IDN?" + Environment.NewLine;
            SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
            string data = string.Empty;
            if (sp.IsOpen)
            {
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
                Thread.Sleep(150);
                byte[] readBuffer = new byte[sp.BytesToRead];
                sp.Read(readBuffer, 0, readBuffer.Length);
                data = System.Text.Encoding.ASCII.GetString(readBuffer);
            }

            //SX-19001A
            if (string.IsNullOrWhiteSpace(data))
            {
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
                Thread.Sleep(150);
                byte[] readBuffer = new byte[sp.BytesToRead];
                sp.Read(readBuffer, 0, readBuffer.Length);
                data = System.Text.Encoding.ASCII.GetString(readBuffer);
            }

            if (string.IsNullOrWhiteSpace(data))
                data = "获取版本号失败，请检查通信是否正常";

            return data;
        }

        public bool Check(SerialPort sp)
        {
            bool flag = false;

            byte[] SendBytes = null;
            string SendData = "*IDN?" + Environment.NewLine;
            SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
            string data = string.Empty;
            if (sp.IsOpen)
            {
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
                Thread.Sleep(150);
                data = GetData(sp);
            }
            else
                return false;


            //SX-19001A
            if (string.IsNullOrWhiteSpace(data))
            {
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
                Thread.Sleep(150);
                data = GetData(sp);
            }
            if (data.Contains("SX-19001A"))
                flag = true;

            return flag;
        }

        public void SetFreq(SerialPort sp, string freq, string freq2,string testItem)
        {
            if (string.IsNullOrWhiteSpace(freq) && string.IsNullOrWhiteSpace(freq2))
                return;
            if (sp.IsOpen)
            {
                try
                {
                    bool isAutoTest = Settings.IsAllAuto();
                    Settings.LcrType lcrType = Settings.GetLcrType();
                    if (!isAutoTest && lcrType == Settings.LcrType.SX10091A)
                    {
                        SetSingleMode(sp);
                        Thread.Sleep(200);
                    }
                }
                catch(Exception ex)
                {
                    Logger.LogError(ex);
                }
            

                //todo:testItem 根據測試參數設置頻率
                //list:dfrq:fa 0.12KHZ
                //list: dfrq: fb 100KHZ
                byte[] SendBytes = null;
                string SendData = string.Empty;
                if(!string.IsNullOrWhiteSpace(freq)) SendData += "list:dfrq: fa " + freq + Environment.NewLine;
                if (!string.IsNullOrWhiteSpace(freq2)) SendData += "list:dfrq: fb " + freq2 + Environment.NewLine;
                 SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
            }
        }
        public void Fetch(SerialPort sp, string testItem)
        {
            if (sp.IsOpen)
            {
                byte[] SendBytes = null;
                string SendData = "FETch:imp:cust?\r\n";
                SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
            }
        }

        /// <summary>
        /// 設置儀器為多頻測試頁X
        /// </summary>
        /// <param name="sp"></param>
        /// <param name="testItem"></param>
        public void SetMutilMode(SerialPort sp)
        {
            if (sp.IsOpen)
            {
                byte[] SendBytes = null;
                string SendData = "disp:page dfm" + Environment.NewLine;
                SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
                Thread.Sleep(200);
                SendData = "FUNCtion:IMPedance CSD" + Environment.NewLine;
                SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
                Thread.Sleep(200);
                SendData = "FUNCtion:IMPedance:CTYPe R" + Environment.NewLine;
                SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
                Thread.Sleep(200);
                SendData = "FUNCtion:IMPedance:DTYPe X" + Environment.NewLine;
                SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
            }
        }

        /// <summary>
        /// 設置儀器為多頻測試頁Z
        /// </summary>
        /// <param name="sp"></param>
        /// <param name="testItem"></param>
        public void SetSingleMode(SerialPort sp)
        {
            if (sp.IsOpen)
            {
                byte[] SendBytes = null;
                string SendData = "disp:page dfm" + Environment.NewLine;
                SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
                Thread.Sleep(200);
                SendData = "FUNCtion:IMPedance CSD" + Environment.NewLine;
                SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
                Thread.Sleep(200);
                SendData = "FUNCtion:IMPedance:CTYPe R" + Environment.NewLine;
                SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
                Thread.Sleep(200);
                SendData = "FUNCtion:IMPedance:DTYPe Z" + Environment.NewLine;
                SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
            }
        }

        /// <summary>
        /// 設置儀器為多頻測試頁
        /// </summary>
        /// <param name="sp"></param>
        /// <param name="testItem"></param>
        public void SetSpeed(SerialPort sp, string speed)
        {
            if (sp.IsOpen)
            {
                byte[] SendBytes = null;
                string SendData = "APERture " + speed + Environment.NewLine;
                SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
            }
        }


        public string GetData(SerialPort sp)
        {
            try
            {
                byte[] readBuffer = new byte[sp.BytesToRead];
                sp.Read(readBuffer, 0, readBuffer.Length);
                return System.Text.Encoding.ASCII.GetString(readBuffer);
            }
            catch (IOException IOEx)
            {
                Logger.LogError(IOEx);
            }
            catch (InvalidOperationException IVOEx)
            {
                Logger.LogError(IVOEx);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
            return "";
        }

        public bool AnalysisData(string rawString, out decimal cap, out decimal df, out decimal z, out decimal r, string testItem,
            string zrfreq)
        {
            cap = df = z = r = 0m; //初始化传出参数
            try
            {
                return AnalysisData(rawString, out cap, out df, out z, out r, testItem,zrfreq, true);
            }
            catch (System.Exception ex)
            {
                Logger.LogError(ex);
                return false;
            }
        }

        public bool AnalysisData(string rawString, out decimal cap, out decimal df, out decimal z, out decimal r, string testItem,
            string zrfreq,bool isRaw)
        {
            cap = df = z = r = 0m; //初始化传出参数
            if (string.IsNullOrEmpty(rawString))
                return false;
            string strData = string.Empty;

            try
            {
                strData = rawString.ToLower();
                string[] a = strData.Split(new string[] { "\r\n" }, StringSplitOptions.None);
                if (a.Length < 1)
                {
                    return false;
                }
                string strData2 = string.Empty;
                for (int i = a.Length - 1; i >= 0; i--)
                {
                    if (!string.IsNullOrWhiteSpace(a[i]))
                    {
                        strData2 = a[i];
                        string[] dataArrTemp = strData2.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        if (dataArrTemp.Length == 5 && dataArrTemp[dataArrTemp.Length - 1] == "0")
                            break;
                    }
                }
                //  C  D   R   X   （Z值要計算）
                //-1.35759E-07,-9.77199E+00,-8.77663E+02,+6.67403E+03,0 
                string[] dataArr = strData2.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                if (dataArr.Length != 5 || dataArr[dataArr.Length-1] != "0")
                {
                    return false;
                }

                string dataCap = dataArr[0];
                string dataDf = dataArr[1];
                string dataR = dataArr[2];
                string dataX = dataArr[3];

                if (string.IsNullOrEmpty(dataCap) || string.IsNullOrEmpty(dataDf)
                    || string.IsNullOrEmpty(dataR) || string.IsNullOrEmpty(dataX))  //第一个值为0表示数据正确
                {
                    return false;
                }

                if (isRaw)  //校正取原始数据
                {
                    //測試模式C D R X 後面還要計算
                    cap = Common.Tools.Convert2Decimal(dataCap)*1000000m;
                    df = Common.Tools.Convert2Decimal(dataDf)*100m;
                    r = Common.Tools.Convert2Decimal(dataR);
                    z = Common.Tools.Convert2Decimal(dataX);
                }
                else
                {
                    //測試模式 C D R Z
                    //cap = Math.Round(Common.Tools.Convert2Decimal(dataCap)*1000000m,2);
                    //df = Math.Round(Common.Tools.Convert2Decimal(dataDf) * 100m, 2);
                    //r = Math.Round(Common.Tools.Convert2Decimal(dataR) * 1000m, 2);
                    //z = Math.Round(Common.Tools.Convert2Decimal(dataX) * 1000m, 2);

                    cap = Common.Tools.Convert2Decimal(dataCap) * 1000000m;
                    df = Common.Tools.Convert2Decimal(dataDf) * 100m;
                    r = Common.Tools.Convert2Decimal(dataR) * 1000m;
                    z = Common.Tools.Convert2Decimal(dataX) * 1000m;
                }

                return true;
            }
            catch (System.Exception ex)
            {
                Logger.LogError(ex);
                throw ex;
            }
        }

        public void Open(SerialPort sp)
        {
            if (sp.IsOpen)
            {
                byte[] SendBytes = null;
                string SendData = "CORR:OPEN:EXEC;*OPC?" + Environment.NewLine;
                SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
            }
        }

        public void Short(SerialPort sp)
        {
            if (sp.IsOpen)
            {
                byte[] SendBytes = null;
                string SendData = "CORR:SHORt:EXEC;*OPC?" + Environment.NewLine;
                SendBytes = System.Text.Encoding.Default.GetBytes(SendData);
                sp.Write(SendBytes, 0, SendBytes.Length);//发送数据
            }
        }

        public void Remote(SerialPort sp)
        {
            
        }

        public void Local(SerialPort sp)
        {
            
        }
    }
}
